using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using EnvDTE;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TestTools.Common;
using Microsoft.VisualStudio.TestTools.Vsip;
using System.ComponentModel;
using Microsoft.VisualStudio.Shell.Interop;

namespace NUnitForVSTS.NUnitTest
{
    /// <summary>
    /// Creates a Visual Studio Integration Package
    /// </summary>
	[PackageRegistration(UseManagedResourcesOnly = true, RegisterUsing = RegistrationMethod.Assembly)]
	[DefaultRegistryRoot(@"Software\Microsoft\VisualStudio\10.0")]
	[InstalledProductRegistration(true, "NUnit Test for VSTS", null, null)]
    [ProvideLoadKey("Standard", "5.1", "NUnit Test for VSTS", "Info Support BV", 1)]
	[ProvideTip(typeof(UnitTest), typeof(NUnitTestTip))]
	[ProvideServiceForTestType(typeof(UnitTest), typeof(ITestService))]
	[RegisterTestTypeNoEditor(typeof(UnitTest), typeof(NUnitTestTip), new[] { ".exe", ".dll"},//, ".cs" },
	    new[] { ResourceIds.NUnitTestIcon, ResourceIds.NUnitTestIcon }, ResourceIds.NUnitTestName)]
    [Guid("18428BF5-286A-4fa0-B399-BB466F9A2BFD")]
	[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
	[ComVisible(true)]
	[ProvideToolWindow(typeof(NUnitTestResultViewWindow), Orientation = ToolWindowOrientation.Left, Style = VsDockStyle.MDI)]
	public sealed class NUnitTestPackage : Package, IVsInstalledProduct
	{
		private static NUnitTestPackage instance;

        /// <summary>
        /// Gets or sets the services.
        /// </summary>
        /// <value>The services.</value>
		public ServiceProvider Services { get; private set; }

        /// <summary>
        /// Gets the instance (singleton patern).
        /// </summary>
        /// <value>The instance.</value>
		internal static NUnitTestPackage Instance
		{
			get
			{
				Debug.Assert(instance != null, "Package needs to be created before Instance is called.");
				return instance;
			}
		}

        /// <summary>
        /// Initializes this instance.
        /// </summary>
		protected override void Initialize()
		{
			base.Initialize();

            #if DEBUG
            // Add a handler for the UnhandledExceptionEvent  
            AppDomain.CurrentDomain.UnhandledException += (o, e) =>
            {
                Console.WriteLine("Package Loader NunitForVS");
                Console.WriteLine(e.ToString());

                File.WriteAllText(@"C:\package.log", e.ToString());
            };
            #endif

			instance = this;

            try
            {
                Services = new ServiceProvider(this);
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
            }
		}

		#region IVsInstalledProduct Members

        /// <summary>
        /// returns the id of the splash graphic.
        /// </summary>
        /// <param name="pIdBmp">id of the BMP.</param>
        /// <returns>S_OK</returns>
		public int IdBmpSplash(out uint pIdBmp)
		{
			pIdBmp = 0;
			return VSConstants.S_OK;
		}

        /// <summary>
        /// returns the id of the about graphic.
        /// </summary>
        /// <param name="pIdIco">The p id ico.</param>
        /// <returns>S_OK</returns>
		public int IdIcoLogoForAboutbox(out uint pIdIco)
		{
			pIdIco = ResourceIds.NUnitTestIcon;
			return VSConstants.S_OK;
		}

        /// <summary>
        /// Returns the official name of this package
        /// </summary>
        /// <param name="pbstrName">Name of the project.</param>
        /// <returns>S_OK</returns>
		public int OfficialName(out string pbstrName)
		{
            pbstrName = "NUnit Test for VSTS";
			return VSConstants.S_OK;
		}

        /// <summary>
        /// Returns details about the package.
        /// </summary>
        /// <param name="pbstrProductDetails">product details.</param>
        /// <returns>S_OK</returns>
		public int ProductDetails(out string pbstrProductDetails)
		{
			pbstrProductDetails = "NUnit integration in Visual Studio.";
			return VSConstants.S_OK;
		}

        /// <summary>
        /// Returns the version of the product
        /// </summary>
        /// <param name="pbstrPID">version</param>
        /// <returns>S_OK</returns>
		public int ProductID(out string pbstrPID)
		{
			pbstrPID = "5.1";
			return VSConstants.S_OK;
		}

		#endregion
	}
}